博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 权限系统设计
阅读量:4683 次
发布时间:2019-06-09

本文共 8508 字,大约阅读时间需要 28 分钟。

权限系统表结构的设计

from django.db import models# Create your models here.class UserInfo(models.Model):    '''    用户表    '''    username=models.CharField(max_length=32,verbose_name='用户名')    password=models.CharField(max_length=64,verbose_name='密码')    roles=models.ManyToManyField(to='Role',verbose_name='拥有角色',)class Role(models.Model):    '''    角色表    '''    title=models.CharField(max_length=32,verbose_name='角色名称')    permissions=models.ManyToManyField(to='Permission',verbose_name='拥有权限')    def __str__(self):        return self.titleclass Permission(models.Model):    '''    权限表    '''    title=models.CharField(max_length=32,verbose_name='权限名称')    url=models.CharField(max_length=255,verbose_name='含权限的URL')    code=models.CharField(max_length=32,verbose_name='权限代码')    group=models.ForeignKey(to='PermissionGroup',verbose_name='所属权限组',on_delete=True)    group_menu=models.ForeignKey(verbose_name='组内菜单',to='self',null=True,blank=True,related_name='gxx',on_delete=True)class PermissionGroup(models.Model):    '''    权限组    '''    caption=models.CharField(max_length=32,verbose_name='权限组名称')    menu=models.ForeignKey(to='Menu',on_delete=True)class Menu(models.Model):    '''    菜单表    '''    title=models.CharField(max_length=32)

权限系统需要在django项目settings.py 中设置如下

PERMISSION_DICT_SESSION_KEY='user_permission_dict_key'   #权限字典存入session中PERMISSION_MENU_SESSION_KEY='user_permission_menu_key'   #权限目录放入session中REX_FORMAT = "^%s$"                        #url的匹配头部和结尾设置VALID_LIST = [                             #url的访问白名单    '/crm/login/',    '^/admin/.*',]

权限系统的app中建立services包,init_permission.py 文件 把权限的url存入session中,把权限的目录存入session中

from  django.conf import settingsdef init_permission(user,request):    '''    登录用户的权限初始化    :param user:登录用户对象    :param request:    :return:    '''    permisssions_list = user.roles.filter(permissions__id__isnull=False).values(        'permissions__id',#权限id        'permissions__title',#权限名称        'permissions__url',#权限url        'permissions__code',#权限code        'permissions__group__id',#权限组id        'permissions__group_menu__id',#是否为组内菜单        'permissions__group__menu__id',#一级菜单id        'permissions__group__menu__title',#一级菜单名称    ).distinct()    #获取权限信息+菜单放入session 中,以后生成动态菜单    permission_menu_list=[]    for item in permisssions_list:        val={            'id':item['permissions__id'],            'title':item['permissions__title'],            'url':item['permissions__url'],            'pid':item['permissions__group_menu__id'],            'menu_id':item['permissions__group__menu__id'],            'menu_name':item['permissions__group__menu__title'],        }        permission_menu_list.append(val)    request.session[settings.PERMISSION_MENU_SESSION_KEY]=permission_menu_list    #获取权限信息放入session中    permission_dict = {}    for permission in permisssions_list:        group_ip = permission['permissions__group__id']        url = permission['permissions__url']        code = permission['permissions__code']        if group_ip in permission_dict:            permission_dict[group_ip]['urls'].append(url)            permission_dict[group_ip]['codes'].append(code)        else:            permission_dict[group_ip] = {
'urls': [url, ], 'codes': [code, ]} request.session[settings.PERMISSION_DICT_SESSION_KEY]=permission_dict

权限系统的app中建立templatetags包,rbac.py 文件  构造权限目录

from django.template import Libraryfrom django.conf import settingsimport reregister=Library()@register.inclusion_tag('rbac/menu.html')def menu(request):    permission_menu_list = request.session[settings.PERMISSION_MENU_SESSION_KEY]    current_url = request.path_info    current_pxe = settings.REX_FORMAT    # 构造二级菜单字典    per_dict = {}    for per_item in permission_menu_list:        if not per_item['pid']:            per_dict[per_item['id']] = per_item    for item in permission_menu_list:        if not re.match(current_pxe % (item['url']), current_url):            continue        if item['pid']:            per_dict[item['pid']]['active'] = True        else:            item['active'] = True    # 生成菜单字典    menu_dict = {}    for menu_item in per_dict.values():        if menu_item['menu_id'] in menu_dict:            menu_dict[menu_item['menu_id']]['children'].append(                {
'id': menu_item['id'], "title": menu_item['title'], 'url': menu_item['url'], 'active': menu_item.get('active', False)}) # menu_item['menu_id']['children'].append({'id':menu_item['id'],"title":menu_item['title'],'url':menu_item['url'],'active':menu_item.get('active',False)}) if menu_item.get('active', False): menu_item['menu_id']['active']: True # menu_item['menu_id']['children'].append({'id':menu_item['id'],"title":menu_item['title'],'url':menu_item['url'],'active':menu_item.get('active',False)}) else: menu_dict[menu_item['menu_id']] = { 'menu_name': menu_item['menu_name'], 'active': menu_item.get('active', False), 'children': [{
'id': menu_item['id'], "title": menu_item['title'], 'url': menu_item['url'], 'active': menu_item.get('active', False)}] } return {
'menu_dict':menu_dict}

权限系统的app中建立templates/rbac/menu.html 文件  构造权限的html页面 

{% for menu in menu_dict.values %}                
{% endfor %}

在 要使用权限系统的app中 的布局页面,中把 menu.html 页面个包含到目录位置

{% load rbac %}    
Title
头部菜单
{% block content %} {% endblock %}

 权限系统中的权限的验证时放在中间件找那个实现的

MIDDLEWARE = [    #'django.middleware.cache.UpdateCacheMiddleware',    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    #'django.middleware.cache.FetchFromCacheMiddleware',    'rbac.middlewares.rbac.RbacMiddleware', # 权限验证的中间件]

权限中间件  在 rbac app 中创建 middlewares包创建rbac.py文件 在其中创建 继承中间件的类,实现用户登录权限的验证。

from django.conf import settingsfrom  django.shortcuts import HttpResponseimport reclass MiddlewareMixin(object):    def __init__(self, get_response=None):        self.get_response = get_response        super().__init__()    def __call__(self, request):        response = None        if hasattr(self, 'process_request'):            response = self.process_request(request)        if not response:            response = self.get_response(request)        if hasattr(self, 'process_response'):            response = self.process_response(request, response)        return responseclass RbacMiddleware(MiddlewareMixin):    def process_request(self,request):       #访问白名单        current_url = request.path_info        white_list=settings.VALID_LIST        # if current_url=='/crm/login/':        #     return None        for valid_item in white_list:            if re.match(valid_item,current_url):                return None        #获取用户的权限信息        permission_dict=request.session.get(settings.PERMISSION_DICT_SESSION_KEY)        #print(permission_dict)        if not permission_dict:            return HttpResponse('当前用户无权限信息.')        #匹配用户是否拥有访问当前页面的权限        flag=False        for permission_item in permission_dict.values():            urls=permission_item['urls']            codes=permission_item['codes']            for itme_url in urls:                reg=settings.REX_FORMAT %(itme_url)                if re.match(reg,current_url):                    request.permission_codes = codes                    print(request.permission_codes)                    flag=True                    break            if flag:                break        if not flag:            return HttpResponse('无权访问.')

 

转载于:https://www.cnblogs.com/hexintong/p/9558711.html

你可能感兴趣的文章
sqlserver一些对象的创建
查看>>
php的json_encode函数问题
查看>>
[转]如何编程实现 2 + 2 = 5?
查看>>
for循环
查看>>
新术语备忘录
查看>>
编译型与解释型
查看>>
5). BlackBerry生命周期- BlackBerry Application Life-Cycle and Phasesby
查看>>
从棋盘左上角到右下角共有多少种走法
查看>>
poj-1031-fence(不是我写的,我只是想看着方便)
查看>>
关于使用easyui dataGrid遇到的小bug问题
查看>>
(转载)用C#实现MySQL建库及建表
查看>>
(转载)MySQL基础(非常全)
查看>>
Nginx+Tomcat实现单IP、多域名、多站点的访问
查看>>
部分手机浏览器存在将ajax请求当成广告过滤的情况,及解决方案
查看>>
数据科学家最常用的十种算法(我准备拿这个当成学习参考)
查看>>
关于setTimeout的面试题
查看>>
fffmgg
查看>>
DOCTYPE用法详解
查看>>
图解闭包
查看>>
android无法创建AVD了?
查看>>